using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;

namespace TmxLib
{
    public class CommandLineParser<T> where T: class, new()
    {
        public static T Parse(string[] args)
        {
            T ret = new T();
            MemberInfo[] members = FindMembers();
            foreach(MemberInfo mi in members)
            {
                string value = Find(args, mi.Name);
                if (value == null)
                    return null;

                PropertyInfo pi = mi as PropertyInfo;
                if (pi != null)
                    pi.SetValue(ret, value, new object[0]);


                FieldInfo fi = mi as FieldInfo;
                if (fi != null)
                    fi.SetValue(ret, value);
            }

            return ret;
        }

        static MemberInfo[] FindMembers()
        {
            List<MemberInfo> list = new List<MemberInfo>();
            MemberInfo[] members = typeof(T).GetMembers();
            foreach (MemberInfo mi in members)
            {
                PropertyInfo pi = mi as PropertyInfo;
                if (pi != null)
                {
                    if (pi.PropertyType == typeof(string) && pi.GetSetMethod().GetParameters().Length == 0)
                    {
                        list.Add(mi);
                    }
                }

                FieldInfo fi = mi as FieldInfo;
                if (fi != null)
                {
                    if (fi.FieldType == typeof(string))
                    {
                        list.Add(mi);
                    }
                }
            }

            return list.ToArray();
        }

        static string Find(string[] args, string name)
        {
            foreach(String a in args)
            {
                if (a.StartsWith("/") || a.StartsWith("-"))
                {
                    int p = a.IndexOf(':');
                    if (p > 0)
                    {
                        string pName = a.Substring(1, p - 1);
                        string pValue = a.Substring(p + 1);

                        if (string.Compare(pName, name, true) == 0)
                        {
                            return pValue;
                        }
                    }
                }
            }

            return null;
        }

        public static string  Usage
        {
            get
            {
                StringBuilder ret = new StringBuilder(Assembly.GetEntryAssembly().GetName().Name + " Usage:");
                ret.AppendLine();

                MemberInfo[] members = FindMembers();
                foreach(MemberInfo m in members)
                {
                    object[] arr = m.GetCustomAttributes(typeof (DescriptionAttribute), false);
                    string description = arr != null && arr.Length > 0 ? (arr[0] as DescriptionAttribute).Description : "<description expected>";
                    ret.AppendFormat("\t/{0}: {1}", m.Name, description);
                    ret.AppendLine();
                }

                return ret.ToString();
            }
        }
    }
}
